#include "a_global_vars.h"
double latency[1500000];
//------------------------------------------------------------------------------
double getMicroseconds() {
	struct timeval mtv;
	gettimeofday(&mtv, NULL);
	double m = 1000 * mtv.tv_sec + mtv.tv_usec / (double) 1000;
	return m;
}//------------------------------------------------------------------------------
void multicaster_deliver(paxos_msg * m) {
	if (!data[(m->instance_number % INTERNAL_BUFFER_SIZE)].deliver && data[(m->instance_number % INTERNAL_BUFFER_SIZE)].received) {
		data[(m->instance_number % INTERNAL_BUFFER_SIZE)].dec = m->VALUE;
		data[(m->instance_number % INTERNAL_BUFFER_SIZE)].deliver = true;
	}
}
//------------------------------------------------------------------------------
void learner_deliver() {
	int i, k;
	bool flag = false;
	for (i = lowestDelivered + 1; i < a_interval_performance->highest_deliverable_inst_id + 1; i++) {
		if (data[(i % INTERNAL_BUFFER_SIZE)].received && data[(i % INTERNAL_BUFFER_SIZE)].packet.pack_id == (i + 1)) {
			if (!MULTICASTER && !data[(i % INTERNAL_BUFFER_SIZE)].deliver) {

				double lat = getMicroseconds() - data[(i % INTERNAL_BUFFER_SIZE)].packet.msgs[0].microseconds;
				a_interval_performance->interval_latency += lat;
				if (a_next_performance_index > DISCARD && a_next_performance_index < STOPPING_CONDITION - DISCARD) {
					latency[a_interval_performance->latency_counter] = lat;
					a_interval_performance->latency_counter++;
				}
				flag = true;

				data[(i % INTERNAL_BUFFER_SIZE)].dec = data[(i % INTERNAL_BUFFER_SIZE)].packet.pack_id;
				data[(i % INTERNAL_BUFFER_SIZE)].deliver = true;
				data[(i % INTERNAL_BUFFER_SIZE)].received = false;
				data[(i % INTERNAL_BUFFER_SIZE)].deliver = false;
				paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vval = data[(i % INTERNAL_BUFFER_SIZE)].packet.pack_id;
				a_interval_performance->interval_num_packets_delivered++;
				a_interval_performance->total_num_packets_delivered++;
				//--------------------------------------------
				if (!COORDINATOR) {
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].rnd = 0;
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vrnd = 0;
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vval = 0;
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].crnd = -1;
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].cval = -1;
				} else {
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].rnd = 0;
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vrnd = 0;
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vval = 0;
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].crnd = 1;// before =0
					paxos_instances[(i % INTERNAL_BUFFER_SIZE)].cval = 0;
				}
			}
			if (MULTICASTER) {
				for (k = 0; k < MAX_MSG_COUNT; k++)
					a_interval_performance->interval_latency += getMicroseconds() - data[(i % INTERNAL_BUFFER_SIZE)].packet.msgs[k].microseconds;
				flag = true;
				data[(i % INTERNAL_BUFFER_SIZE)].dec = data[(i % INTERNAL_BUFFER_SIZE)].packet.pack_id;
				data[(i % INTERNAL_BUFFER_SIZE)].received = false;
				data[(i % INTERNAL_BUFFER_SIZE)].deliver = false;
				paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vval = data[(i % INTERNAL_BUFFER_SIZE)].packet.pack_id;
				a_interval_performance->interval_num_packets_delivered++;
				a_interval_performance->total_num_packets_delivered++;
				//---------------------------------------------------
				paxos_instances[(i % INTERNAL_BUFFER_SIZE)].rnd = 0;
				paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vrnd = 0;
				paxos_instances[(i % INTERNAL_BUFFER_SIZE)].vval = 0;
				paxos_instances[(i % INTERNAL_BUFFER_SIZE)].crnd = -1;
				paxos_instances[(i % INTERNAL_BUFFER_SIZE)].cval = -1;
			}
		}
	}
	if (flag)
		lowestDelivered = i - 1;
}
//------------------------------------------------------------------------------
